﻿#include "CapThreadV4L2.h"
#include <QFileInfo>
//#include "configini.h"
#include "CameraGrab.h"



CapThreadV4L2::CapThreadV4L2(QObject *parent )
{

   m_parent = parent;


   m_pChnCfg = (stChnV4L2*)calloc(1,sizeof(stChnV4L2));



   m_pTmpFrame = new uint8_t[FRAME_MAX_LEN];

   m_pScaleYUV = new uint8_t[FRAME_MAX_LEN];


   m_nVisibleWidth  = 1920;
   m_nVisibleHeight = 1080;

   m_nFps_tv = 0;
   m_nFps_ir = 0;
   m_nFrameCnt = 0;
   m_ThreadRun = true;
}


void   CapThreadV4L2::SetChannel(int chn)
{
    int k;

    if(m_pChnCfg)
    {
        m_pChnCfg->nChannel = chn;

        for(k=0; k<MAX_FRAME_BUFF_CNT; k++)
        {
            m_pChnCfg->m_pFrame[k] = new stVFrame();

        }

        m_pChnCfg->v4l2_fd = -1;



          CapInitAlgV4l2(m_pChnCfg->nChannel);




    }

}



void CapThreadV4L2::CapInitAlgV4l2(int nChn)
{



       //这里应该是算法输出后的分辨率，最后要根据算法设置
        strcpy(m_pChnCfg->cChnName,"/dev/video0");
        m_pChnCfg->nCapWidth = m_nVisibleWidth;
        m_pChnCfg->nCapHeight = m_nVisibleHeight;
        m_pChnCfg->m_nAlgWidth = m_nVisibleWidth;
        m_pChnCfg->m_nAlgHeight = m_nVisibleHeight;
        m_pChnCfg->m_fMinScale = 1.0;



    start_cap_dev(m_pChnCfg);

}





CapThreadV4L2::~CapThreadV4L2()
{
    int i,k;

    for(k=0; k<MAX_FRAME_BUFF_CNT; k++)
    {
        SAFE_DELETE(m_pChnCfg->m_pFrame[k]);
    }

    stop_capturing(m_pChnCfg);

    SAFE_DELETE_ARRAY(m_pTmpFrame);
    SAFE_DELETE_ARRAY(m_pScaleYUV);



}


void CapThreadV4L2::run()
{


    int nRes = 0;


    start_cap_stream(m_pChnCfg);

    while(m_ThreadRun)
    {

        nRes =  SelectGetFrame();

    }



}




QString  CapThreadV4L2::GetCapInfo(int chn)
{
    QString result;
    const char* pSrcTypeStr[] =
    {
        "picture",
        "movie",
        "rtsp stream",
        "rockchip v4l2"
    };

    const char* pChannName[] =
    {
       "可见光",
       "红外",
        "未知"
    };


    return result;
}

int CapThreadV4L2::SelectGetFrame()
{
    fd_set fds;
    struct timeval tv;
    int r;
    int  fd_max = 0;



    FD_ZERO(&fds);



    FD_SET(m_pChnCfg->v4l2_fd, &fds);
    if(m_pChnCfg->v4l2_fd > fd_max)
    {
        fd_max = m_pChnCfg->v4l2_fd;
    }

    // Timeout
    tv.tv_sec = 2;
    tv.tv_usec = 0;

    r = select(fd_max + 1, &fds, NULL, NULL, &tv);
    if (-1 == r) {
        if (EINTR == errno)
            return -1;

    }

    if (0 == r)
    {
         return -1;
    }


         if (FD_ISSET( m_pChnCfg->v4l2_fd, &fds ))
         {
             int nPos = m_pChnCfg->m_nWritePos;

             m_pChnCfg->m_pFrame[nPos]->nWidth = m_pChnCfg->m_nAlgWidth;
             m_pChnCfg->m_pFrame[nPos]->nHeight = m_pChnCfg->m_nAlgHeight;
             m_pChnCfg->m_pFrame[nPos]->nChannel = m_pChnCfg->nChannel;
             m_pChnCfg->m_pFrame[nPos]->nDataLen =
                     m_pChnCfg->m_nAlgWidth*m_pChnCfg->m_nAlgHeight*3;



                if(read_frame(m_pChnCfg,m_pChnCfg->m_pFrame[nPos],ucVideoCtrl2,m_pScaleYUV,m_pTmpFrame))
                {
                   m_nFrameCnt++;


                   m_pChnCfg->m_nSeq++;
                   m_pChnCfg->m_pFrame[nPos]->nSeq = m_pChnCfg->m_nSeq;

                   m_pChnCfg->m_nWritePos = (m_pChnCfg->m_nWritePos+1)%MAX_FRAME_BUFF_CNT;



                       if(m_nFps_tv < MAX_ALG_FPS)
                       {

                           emit AlgProcFrame(m_pChnCfg->m_pFrame[nPos]);
                            m_nFps_tv++;
                       }


              }
        }
       return 0;
}
void CapThreadV4L2::Stop()
{
   m_ThreadRun = 0;
}



